#include <mips/regdef.h>
#include <sys/syscall.h>
#include "Definitions.h"

	.text
	.align	2
	.globl	main
	.ent	main
/****************************************************************/
main:
	.frame	$fp,STACK_BYTE_SIZE,ra
	.set	noreorder
	.cpload	t9
	.set	reorder
	subu	sp,sp,STACK_BYTE_SIZE
	.cprestore 16
	sw		ra,OFFSET_RET_ADDR(sp)
	sw		$fp,OFFSET_FRAME_POINTER(sp)
	sw		gp, OFFSET_GLOBAL_POINTER(sp)
	move	$fp,sp
	#variables locales
	sw	a0,STACK_BYTE_SIZE($fp)
	sw	a1,STACK_BYTE_SIZE+WORD_SIZE($fp)
	sw	zero,OFFSET_LOCAL_AND_TEMP_AREA+GET_BYTES_OF_LINES(3)($fp)
	li	v0,BUFFER_SIZE			
	sw	v0,OFFSET_LOCAL_AND_TEMP_AREA+GET_BYTES_OF_LINES(4)($fp)		#buffer_size
	sw	zero,OFFSET_LOCAL_AND_TEMP_AREA+GET_BYTES_OF_LINES(5)($fp)	#last_char 

	#llamo a mymalloc
	lw		a0,OFFSET_LOCAL_AND_TEMP_AREA+GET_BYTES_OF_LINES(4)($fp)
	la		t9,mymalloc
	jal		ra,t9
	sw		v0,POS_BUFFER_RETURN($fp)		#guardo lo devuelto en buffer
/****************************************************************/
while_1:
	la	t9,mygetchar
	jal	ra,t9
	sb	v0,OFFSET_LOCAL_AND_TEMP_AREA+GET_BYTES_OF_LINES(2)($fp)
	lbu	v0,OFFSET_LOCAL_AND_TEMP_AREA+GET_BYTES_OF_LINES(2)($fp)
	sll 	v0,v0,OFFSET_LOCAL_AND_TEMP_AREA+GET_BYTES_OF_LINES(2)
	sra	v1,v0,OFFSET_LOCAL_AND_TEMP_AREA+GET_BYTES_OF_LINES(2)
	li	v0,END_VAL			
	beq	v1,v0,while_1_fin
	lw	t0,POS_BUFFER_RETURN($fp)		
	lw	t1,OFFSET_LOCAL_AND_TEMP_AREA+GET_BYTES_OF_LINES(5)($fp)
	addu	t0,t1,t0		#buffer + last_char
	lbu	t1,OFFSET_LOCAL_AND_TEMP_AREA+GET_BYTES_OF_LINES(2)($fp)
	sb	t1,0(t0)			#guardo un_char en *(buffer + last_char)
	ADDU_TO_LINE_IN_LTA(5,5,1)
	lw	t1,OFFSET_LOCAL_AND_TEMP_AREA+GET_BYTES_OF_LINES(4)($fp)
	bne	t0,t1,while_1		#if (last_char == buffer_size)
	SLL_OF_LINE_IN_LTA(4,4,1)
	lw	a0,OFFSET_LOCAL_AND_TEMP_AREA+GET_BYTES_OF_LINES(4)($fp)
	la	t9,mymalloc
	jal	ra,t9
	sw	v0,OFFSET_LOCAL_AND_TEMP_AREA+GET_BYTES_OF_LINES(9)($fp)			#buffer_aux = mymalloc(buffer_size)
	sw	zero,OFFSET_LOCAL_AND_TEMP_AREA+GET_BYTES_OF_LINES(3)($fp)
/****************************************************************/
for_1:
	lw	t0,OFFSET_LOCAL_AND_TEMP_AREA+GET_BYTES_OF_LINES(3)($fp)
	lw	t1,OFFSET_LOCAL_AND_TEMP_AREA+GET_BYTES_OF_LINES(5)($fp)
	sltu	v0,v0,v1	
	bltu	t0,t1,for_1_sigue
	b	for_1_fin
/****************************************************************/
for_1_sigue:
	lw	t0,OFFSET_LOCAL_AND_TEMP_AREA+GET_BYTES_OF_LINES(9)($fp)
	lw	t1,OFFSET_LOCAL_AND_TEMP_AREA+GET_BYTES_OF_LINES(3)($fp)
	addu	t2,t0,t1		#buffer_aux + i 
	lw	t0,OFFSET_LOCAL_AND_TEMP_AREA+GET_BYTES_OF_LINES(8)($fp)
	lw	t1,OFFSET_LOCAL_AND_TEMP_AREA+GET_BYTES_OF_LINES(3)($fp)
	addu	t3,t0,t1		#buffer + i
	lbu	t0,0(t3)
	sb	t0,0(t2)			#*(buffer_aux + i) = *(buffer + i);
	ADDU_TO_LINE_IN_LTA(3,3,1)
	b	for_1
/****************************************************************/
for_1_fin:
	lw	a0,OFFSET_LOCAL_AND_TEMP_AREA+GET_BYTES_OF_LINES(8)($fp)
	la	t9,myfree
	jal	ra,t9				#myfree(buffer);
	COPY_TO_LINE_USING_T0(9,8)
	b	while_1
/****************************************************************/
while_1_fin:
	COPY_TO_LINE_USING_V0(5,6)
	COPY_TO_LINE_USING_V0(5,7)
/****************************************************************/
while_2:
	lw	t0,OFFSET_LOCAL_AND_TEMP_AREA+GET_BYTES_OF_LINES(6)($fp)
	beq	t0,zero,while_2_fin
/****************************************************************/
while_2_1:	
	lw	t0,OFFSET_LOCAL_AND_TEMP_AREA+GET_BYTES_OF_LINES(8)($fp)
	lw	t1,OFFSET_LOCAL_AND_TEMP_AREA+GET_BYTES_OF_LINES(6)($fp)
	addu	t0,t1,t0		#buffer + actual_char
	lb	t0,0(t0)
	li	t1,10			
	beq	t0,t1,while_2_1_fin	
	lw	t0,OFFSET_LOCAL_AND_TEMP_AREA+GET_BYTES_OF_LINES(6)($fp)
	beq	t0,zero,while_2_1_fin	#if (actual_char == 0) break;
	ADDU_TO_LINE_IN_LTA(6,6,-1)
	b	while_2_1
/****************************************************************/
while_2_1_fin:
	lw	t0,OFFSET_LOCAL_AND_TEMP_AREA+GET_BYTES_OF_LINES(6)($fp)
	beq	t0,zero,while_2_1_fin	#if (actual_char == 0) break;
	ADDU_TO_LINE_IN_LTA(6,3,1)
/****************************************************************/
for_2:
	lw	t0,OFFSET_LOCAL_AND_TEMP_AREA+GET_BYTES_OF_LINES(3)($fp)
	lw	t1,OFFSET_LOCAL_AND_TEMP_AREA+GET_BYTES_OF_LINES(7)($fp)
	sltu	v0,v1,v0
	bleu	t0,t1,for_2_sigue	#condicion de salto del for
	b	for_2_fin
/****************************************************************/	
for_2_sigue:
	lw	t0,OFFSET_LOCAL_AND_TEMP_AREA+GET_BYTES_OF_LINES(8)($fp)
	lw	t1,OFFSET_LOCAL_AND_TEMP_AREA+GET_BYTES_OF_LINES(3)($fp)
	addu	t0,t0,t1
	lb	t0,0(t0)
	move	a0,t0
	la	t9,myputchar
	jal	ra,t9					#myputchar(*(buffer + i));
	ADDU_TO_LINE_IN_LTA(3,3,1)
	b	for_2
/****************************************************************/	
for_2_fin:
	lw	t0,OFFSET_LOCAL_AND_TEMP_AREA+GET_BYTES_OF_LINES(6)($fp)				#end_line_char = actual_char
	sw	t0,OFFSET_LOCAL_AND_TEMP_AREA+GET_BYTES_OF_LINES(7)($fp)
	lw	t0,OFFSET_LOCAL_AND_TEMP_AREA+GET_BYTES_OF_LINES(6)($fp)
	addu	t0,t0,-1
	sw	v0,OFFSET_LOCAL_AND_TEMP_AREA+GET_BYTES_OF_LINES(6)($fp)				#actual_char--
	b	while_2
/****************************************************************/	
while_2_fin:
	sw	zero,OFFSET_LOCAL_AND_TEMP_AREA+GET_BYTES_OF_LINES(3)($fp)
/****************************************************************/	
for_3:
	lw	t0,OFFSET_LOCAL_AND_TEMP_AREA+GET_BYTES_OF_LINES(3)($fp)
	lw	t1,OFFSET_LOCAL_AND_TEMP_AREA+GET_BYTES_OF_LINES(7)($fp)
	sltu	v0,v0,v1
	bleu	t0,t1,for_3_sigue	#condicion de salto del for
	b	for_3_fin
/****************************************************************/	
for_3_sigue:
	lw	t0,OFFSET_LOCAL_AND_TEMP_AREA+GET_BYTES_OF_LINES(8)($fp)
	lw	t1,OFFSET_LOCAL_AND_TEMP_AREA+GET_BYTES_OF_LINES(3)($fp)
	addu	t0,t0,t1
	lb	t0,0(t0)
	move	a0,t0
	la	t9,myputchar
	jal	ra,t9					#myputchar(*(buffer + i))
	ADDU_TO_LINE_IN_LTA(3,3,1)
	b	for_3
/****************************************************************/	
for_3_fin:
	lw	a0,OFFSET_LOCAL_AND_TEMP_AREA+GET_BYTES_OF_LINES(8)($fp)
	la	t9,myfree
	jal	ra,t9					#myfree(buffer)
	move	v0,zero				#valor devuelto
	move	sp,$fp				#desapilo stack
	lw	ra,OFFSET_RET_ADDR(sp)
	lw	$fp,OFFSET_FRAME_POINTER(sp)
	addu	sp,sp,STACK_BYTE_SIZE
	j	ra
	.end	main
